package com.deruan.hotcore.resource.command;

import java.util.Date;

import javax.swing.JOptionPane;

import org.columba.api.command.ICommandReference;
import org.columba.api.command.IWorkerStatusController;
import org.columba.api.gui.frame.IFrameMediator;
import org.columba.api.selection.ISelectionListener;
import org.columba.api.selection.SelectionChangedEvent;
import org.columba.core.command.Command;
import org.columba.core.command.CommandCancelledException;
import org.columba.core.command.StatusObservableImpl;
import org.columba.core.context.base.api.IStructureValue;
import org.columba.core.context.semantic.api.ISemanticContext;
import org.columba.core.gui.frame.FrameManager;
import org.columba.core.util.NameParser;
import org.columba.mail.command.IMailFolderCommandReference;
import org.columba.mail.folder.AbstractMessageFolder;
import org.columba.mail.folder.FolderInconsistentException;
import org.columba.mail.folder.IMailFolder;
import org.columba.mail.folder.IMailbox;
import org.columba.mail.folder.headercache.SyncHeaderList;
import org.columba.mail.gui.frame.MailFrameMediator;
import org.columba.mail.gui.frame.MessageViewOwner;
import org.columba.mail.gui.message.IMessageController;
import org.columba.mail.gui.message.viewer.MarkAsReadTimer;
import org.columba.mail.gui.table.selection.ResourceTableSelectionChangedEvent;
import org.columba.mail.gui.table.selection.TableSelectionChangedEvent;
import org.columba.mail.util.MailResourceLoader;
import org.columba.ristretto.message.Address;
import org.columba.ristretto.message.Flags;

import com.deruan.hotcore.resource.gui.tree.ResourceTreeNode;
import com.deruan.hotcore.resource.gui.tree.ResultTreeNode;

public class ViewResourceCommand extends Command implements ISelectionListener
{
	private Flags flags;

	private IMailbox srcFolder;

	private Object uid;

	private IFrameMediator mediator;

	private boolean updateGui;

	private IStructureValue value;

	private String subject;

	private String bodyText;

	private Date date;

	private NameParser.Name name;

	private Address from;

	/**
	 * Constructor for ViewMessageCommand.
	 *
	 * @param references
	 */
	public ViewResourceCommand(IFrameMediator mediator,ICommandReference reference) 
	{
		super(reference);
		this.mediator = mediator;
		priority = Command.REALTIME_PRIORITY;
		//commandType = Command.NORMAL_OPERATION;
		updateGui = true;

		// Register as listener to the SelectionManger
		// to check for selection changes
		((MailFrameMediator) mediator).registerResourceTableSelectionListener(this);
	}

	/**
	 * @see org.columba.api.command.Command#updateGUI()
	 */
	public void updateGUI() throws Exception 
	{
		((MailFrameMediator) mediator).removeTableSelectionListener(this);

		// Update only if the selection did not change
		if (updateGui) 
		{
			IMessageController messageController = ((MessageViewOwner) mediator)
					.getMessageController();

			// display changes
			messageController.updateGUI();

			fillContext();
		}
	}

	private void fillContext() {
		if ( value == null) return;

		// create identity value
		IStructureValue identity = value.addChild(
				ISemanticContext.CONTEXT_NODE_IDENTITY,
				ISemanticContext.CONTEXT_NAMESPACE_CORE);
		if (name != null && name.toString() != null)
			identity.setString(ISemanticContext.CONTEXT_ATTR_DISPLAY_NAME,
					ISemanticContext.CONTEXT_NAMESPACE_CORE, name.toString());
		if (from != null && from.getMailAddress() != null)
			identity.setString(ISemanticContext.CONTEXT_ATTR_EMAIL_ADDRESS,
					ISemanticContext.CONTEXT_NAMESPACE_CORE, from
							.getMailAddress());
		if (name != null && name.getFirstName() != null)
			identity.setString(ISemanticContext.CONTEXT_ATTR_FIRST_NAME,
					ISemanticContext.CONTEXT_NAMESPACE_CORE, name
							.getFirstName());
		if (name != null && name.getLastName() != null)
			identity
					.setString(ISemanticContext.CONTEXT_ATTR_LAST_NAME,
							ISemanticContext.CONTEXT_NAMESPACE_CORE, name
									.getLastName());

		// create message value
		IStructureValue message = value.addChild(
				ISemanticContext.CONTEXT_NODE_MESSAGE,
				ISemanticContext.CONTEXT_NAMESPACE_CORE);
		if (subject != null)
			message.setString(ISemanticContext.CONTEXT_ATTR_SUBJECT,
					ISemanticContext.CONTEXT_NAMESPACE_CORE, subject);
		if (date != null)
			message.setDate(ISemanticContext.CONTEXT_ATTR_DATE,
					ISemanticContext.CONTEXT_NAMESPACE_CORE, date);

		IMessageController messageController = ((MessageViewOwner) mediator)
				.getMessageController();

		bodyText = messageController.getText();

		// @TODO: assert(bodyText != null) or if (bodyText != null)
		message.setString(ISemanticContext.CONTEXT_ATTR_BODY_TEXT,
				ISemanticContext.CONTEXT_NAMESPACE_CORE, bodyText);

		// set value
		mediator.getSemanticContext().setValue(value);
	}

	/**
	 * @see org.columba.api.command.Command#execute(Worker)
	 */
	public void execute(IWorkerStatusController wsc) throws Exception 
	{
		if (!updateGui)
			return;
		// get command reference
		ICommandReference r = (ICommandReference) getReference();
		if(r instanceof IMailFolderCommandReference)
		{
            //get selected folder
			srcFolder = (IMailbox)((IMailFolderCommandReference) r).getSourceFolder();

			// register for status events
			((StatusObservableImpl) srcFolder.getObservable()).setWorker(wsc);

			// get selected message UID
			uid = ((IMailFolderCommandReference) r).getUids()[0];

			try {
				// get messagecontroller of frame
				IMessageController messageController = ((MessageViewOwner) mediator)
						.getMessageController();

				messageController.showResource(srcFolder, uid);

				// fill semantic context
				//prepareContextData();
			} catch (FolderInconsistentException e) {
				Object[] options = new String[] { MailResourceLoader.getString("",
						"global", "ok").replaceAll("&", ""), };
				int result = JOptionPane.showOptionDialog(FrameManager.getInstance()
						.getActiveFrame(), MailResourceLoader
						.getString("dialog", "error", "message_deleted"), "Error",
						JOptionPane.YES_NO_OPTION, JOptionPane.ERROR_MESSAGE, null,
						null, null);

				if (result == JOptionPane.YES_OPTION) {
					// Synchronize the complete folder
					SyncHeaderList.sync((AbstractMessageFolder) srcFolder,
							srcFolder.getHeaderList());
				}

				throw new CommandCancelledException();
			}
		}else if (r instanceof ResultCommandReference) 
		{
            //get selected folder
			ResultTreeNode node = ((ResultCommandReference) r).getSelectedNode();
			try {
				// get messagecontroller of frame
				IMessageController messageController = ((MessageViewOwner) mediator)
						.getMessageController();
                if(node instanceof ResourceTreeNode)
				messageController.showResult(node);

				// fill semantic context
				//prepareContextData();
			} catch (FolderInconsistentException e) 
			{
				
			}
		}

		
	}

	private void prepareContextData() throws Exception {

		// create empty value
		value = mediator.getSemanticContext().createValue();

		// from email address
		Object fromObj = srcFolder.getAttribute(uid, "columba.from");
		if (fromObj instanceof Address) {
			name = NameParser.getInstance().parseDisplayName(((Address)fromObj).getDisplayName());
			from = (Address) fromObj;
		} else if ( fromObj instanceof String){
			name = NameParser.getInstance().parseDisplayName((String) fromObj);
		}

		subject = (String) srcFolder.getAttribute(uid, "columba.subject");
		date = (Date) srcFolder.getAttribute(uid, "columba.date");

	}

	private void restartMarkAsReadTimer(Flags flags,
			IMessageController messageController, IMailFolderCommandReference r)
			throws Exception {

		if (flags == null)
			return;
		// if the message it not yet seen
		if (!flags.getSeen() && !srcFolder.isReadOnly()) {
			MarkAsReadTimer.getInstance().start(messageController, r);
		}
	}

	/**
	 * @see org.columba.api.selection.ISelectionListener#selectionChanged(org.columba.api.selection.SelectionChangedEvent)
	 */
	public void selectionChanged(SelectionChangedEvent e) {

		// old command-specific selection
		/*
		IMailFolderCommandReference r = (IMailFolderCommandReference) getReference();

		// get selected folder
		IMailbox folder = (IMailbox) r.getSourceFolder();

		// get selected message UID
		Object[] uid = r.getUids();

		// new selection
		IMailFolder newFolder = ((ResourceTableSelectionChangedEvent) e).getFolder();
		Object[] newUid = ((ResourceTableSelectionChangedEvent) e).getUids();

		// abort if nothing selected
		if (folder == null)
			return;
		if (newUid == null || newUid.length == 0)
			return;

		// cancel command execution/updateGUI methods, if folder or message
		// selection has been modified
		//if (folder.getId() != newFolder.getId())
			//updateGui = false;

		//if (uid[0].equals(newUid[0]) == false)
			//updateGui = false;
*/
	}
	
}
